#!/usr/bin/env python
# coding: utf-8

import os
import re
import shutil
import zipfile
import time
import datetime
import string
from onshs.ne.tnxxx.tnxxxcfg_basecase import *


log_node_prefix = "vccvcheck"
log_node_fail = log_node_prefix+r"_fail"
log_node_success = log_node_prefix+r"_success"
log_node_summary = log_node_prefix+r"_summary"

log_file_notexisted_fail = "the file:%s isn't existed\n"
log_connect_fail         = "connect ip:%s failed\n"
log_master_opca_fail     = "get ip:%s master opca is failed\n"

log_vccv_fail = "ip:%s pwid:%s have no vccv configuration.\n"
log_vccv_success = "ip:%s pwid:%s have vccv configuration, and the private lable of vccv is %s\n"

log_apsstate_switch_success    = "ip:%s lspid = %s lspname = %s mplsaps switch success, vccv and mplsaps is in the same direction\n"
log_apsstate_switch_fail       = "ip:%s lspid = %s lspname = %s mplsaps switch success, vccv and mplsaps is not in the same direction\n"
log_apsstate_no_switch_success = "ip:%s lspid = %s lspname = %s mplsaps has no switch,, vccv and mplsaps is in the same direction\n"
log_apsstate_no_switch_fail    = "ip:%s lspid = %s lspname = %s mplsaps has no switch, vccv and mplsaps is not in the same direction\n"
log_apsstate_no_information_success = "ip:%s lspid = %s have no mplsaps configuration\n"

log_summary_success = "ip:%s success\n"
log_summary_fail = "ip:%s fail\n"

class TestCase(TnxxxCfg_BaseCase):
    """
    TestCase
    """
    OPTIONS = [        
        {
            'opt' : '--cfgfile',
            'dest': 'cfgfile',
            'metavar' : 'CFGFILE',
            'help' : 'the file of ip list configuration',
            'required' : False,
            'default' : "ip.txt"
        },        
    ]
    
        #初始化信息
    def info_init(self):
        self.info_dic = {}  

        return True
    
    #得到IPLIST
    def get_iplist(self):
        iplist_filted = []                
        if os.path.isfile(os.getcwd()+r'/'+ self.iplistfile):
            iplist = open(os.getcwd()+r'/'+ self.iplistfile)            
        else:
            self.info_show(log_node_fail, log_file_notexisted_fail%(self.iplistfile))            
            return iplist_filted 
        
        for line in iplist:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注释行            
            iplist_filted.append(line.strip('\n'))        
            
        iplist.close()
        
        return iplist_filted
    
    #跟LOG相关函数
    def info_show(self, node, info):
        if not self.info_dic.has_key(node):
            self.info_dic[node] = ""
        self.info_dic[node] += info + '\n'
        return True

    def info_file_clear(self):
        if os.path.exists(self.work_path+r'/common_log'):
            shutil.rmtree(self.work_path+r'/common_log')
        
        return True    
    
    def info_file_save(self):
        path = self.work_path+'//'
        if not os.path.isdir(path):
            os.makedirs(path)
        for node in self.info_dic:
            info_list = open(path+node+'_'+self.worktime+'.txt','a')            
            info_list.write(self.info_dic[node])
            info_list.close()
        return True
        
    #得到Private Lable LIST
    def get_private_lable_list(self):
        #pw lable list-----6000端口
        pw_list = []
        #private lable list -----------23端口
        private_lable_list = []
        
        #查询所有pw，解析出pwid
        cmd = r"show pw"
        rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, CLI_PORT)
        #得到PWID,以PwId：（\d）,匹配得到id，配置pwid为5位
        pw_list = re.findall(r"PwId:\s+(\d+)+.+", rtn_str, 0)
        
        for pw in pw_list:
            #得到VCCV的状态信息，解析出private lable
            cmd =  r"g_dbg_GetVccvStatus %d" % int(pw)
            rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, DEV_PORT)
            
            #私有标签为4位
            lable = re.findall(r"Mpls Label\*+\r\nLabel:(\d+)+\s+", rtn_str, 0)
            
            if [] == lable:
                #记录该pwid不存在vccv信息
                self.info_show(log_node_success, log_vccv_fail%(self.get_ne_ip(0),pw))
            else:
                #空列表直接加第一个元素                
                if lable not in private_lable_list:
                    private_lable_list.append(lable)
                    
                self.info_show(log_node_success, log_vccv_success%(self.get_ne_ip(0),pw, lable[0]))
                
                
                """
                if len(private_lable_list) == 0:
                    private_lable_list.append(lable)
                    self.info_show(log_node_success, log_vccv_success%(self.get_ne_ip(0),pw, lable))
                else:
                    #重复的lable值不添加
                    length = 0
                    for dump_lable in private_lable_list:
                        if dump_lable != lable:
                            length = length + 1
                        else:
                            #记录重复的私有lable
                            self.info_show(log_node_success, log_vccv_success%(self.get_ne_ip(0),pw, lable))
                            continue
                    #如果循环到最后没有重复就添加到列表
                    if length == len(private_lable_list):      
                        private_lable_list.append(lable)
                        self.info_show(log_node_success, log_vccv_success%(self.get_ne_ip(0),pw, lable))
                """
                

        return private_lable_list
    
    #校验当前的状态是否正确
    def get_mplsaps_status(self, label_list):
        ret_value = []
        for label in label_list:
            cmd = '$.dbgcli.0.Cmd "queryasyn valid 1, MplsXcCfg, (LspId), PrivateLabel=%d "'% int(label[0])
            rtn_str = None        
            rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, MTN_PORT)
            if [] == re.findall('success', rtn_str):   
                return ret_value
            else:            
                lspid_list = re.findall('"(.+?)"',rtn_str)
                
                for lspid in lspid_list:
                    #查询该LSPid的名称
                    cmd = '$.dbgcli.0.Cmd "queryasyn valid 1, MplsXcCfg, (Name), (LspId=\'%s\')"'%(lspid)
                    rtn_str = None        
                    rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, MTN_PORT)
                    lsp_name = re.findall('"(.+)".+',rtn_str)
                    
                    #查询到换过的情况
                    cmd = '$.dbgcli.0.Cmd "queryasyn valid 1, MplsApsStat, (WorkLsp), (SecLsp=\'%s\')AND(ApsState=2)"'%(lspid)
                    rtn_str = None        
                    rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, MTN_PORT)
                    worklsp_apsstate_list = re.findall('"(.+)".+',rtn_str)
                    
                    if [] == worklsp_apsstate_list:
                        #没找到就在第二种情况中找
                        #如果没有倒换
                       cmd = '$.dbgcli.0.Cmd "queryasyn valid 1, MplsApsStat, (WorkLsp), (PriLsp=\'%s\')AND(ApsState=0)"'%(lspid)
                       rtn_str = None        
                       rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, MTN_PORT)
                       worklsp_apsstate_list = re.findall('"(.+)".+',rtn_str)
                
                       if [] == worklsp_apsstate_list:
                            #记录在倒换和没有倒换中都查询不到出错
                            #需要pri and sec has no information
                            cmd = '$.dbgcli.0.Cmd "queryasyn valid 1, MplsApsStat, (WorkLsp), (PriLsp=\'%s\')OR(SecLsp=\'%s\')"'%(lspid,lspid)
                            rtn_str = None        
                            rtn_str = self.tnxxx.send_rtn_str(cmd, self.get_ne_ip(0), 0, MTN_PORT)
                            worklsp_apsstate_list = re.findall('"(.+)".+',rtn_str)
                            
                            if [] == worklsp_apsstate_list:
                                self.info_show(log_node_success, log_apsstate_no_information_success%(self.get_ne_ip(0), lspid))
                            else:
                                self.info_show(log_node_fail, log_apsstate_switch_fail%(self.get_ne_ip(0),lspid,lsp_name))
                                ret_value.append("false")
                       else:
                            #检查worklsp 是否等于 lspid
                            if worklsp_apsstate_list[0] == lspid:
                                #没有倒换但是成功
                                self.info_show(log_node_success, log_apsstate_no_switch_success%(self.get_ne_ip(0), lspid,lsp_name))
                            else:
                                #倒换失败
                                self.info_show(self.log_node_fail, log_apsstate_no_switch_fail%(self.get_ne_ip(0), lspid,lsp_name))
                                ret_value.append("false")
                    else:
                        #检查worklsp 是否等于 lspid
                        if worklsp_apsstate_list[0] == lspid:
                            #倒换成功
                            self.info_show(log_node_success, log_apsstate_switch_success%(self.get_ne_ip(0), lspid,lsp_name))
                        else:
                            #倒换失败
                            self.info_show(log_node_fail, log_apsstate_switch_fail%(self.get_ne_ip(0), lspid,lsp_name))
                            ret_value.append("false")
        return ret_value
    
    def _execute(self):
        self.work_path = os.getcwd()+'//'+log_node_prefix
        self.info_init()
        
        worktime = str(datetime.datetime.now())
        self.worktime = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        self.iplistfile = self.options.cfgfile
        
        self.info_show(log_node_summary, "The operation begin time %s \n"%(self.worktime))
        
        ip_list = self.get_iplist()         
   
        for ip in ip_list:
            self.set_ne_ip(0, ip)
            
            #查询私有标签
            private_lable_list = self.get_private_lable_list()
            
            if [] == private_lable_list:
                #没有VCCV的配置就直接跳过
                self.info_show(log_node_summary, log_summary_success%(ip))
                continue
            #查询状态信息       
            if [] == self.get_mplsaps_status(private_lable_list):
                self.info_show(log_node_summary, log_summary_success%(ip))
            else:
                self.info_show(log_node_summary, log_summary_fail%(ip))
            
        worktime = str(datetime.datetime.now())
        self.worktime_end = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        
        self.info_show(log_node_summary, "The operation end time %s "%(self.worktime_end))

        self.info_file_save() 
        return True
    
if __name__ == "__main__" :
    case = TestCase()
    case.execute()